package org.aeon.gamechatnest.service.impl;

import org.aeon.gamechatnest.common.Constant;
import org.aeon.gamechatnest.common.response.RespStatus;
import org.aeon.gamechatnest.common.response.Result;
import org.aeon.gamechatnest.common.response.ResultBuild;
import org.aeon.gamechatnest.dto.ChannelSyncMessageDto;
import org.aeon.gamechatnest.pojo.ChatMessage;
import org.aeon.gamechatnest.pojo.TextChannel;
import org.aeon.gamechatnest.service.ChannelChatMessageService;
import org.aeon.gamechatnest.service.ServerMembersService;
import org.aeon.gamechatnest.service.TextChannelService;
import org.aeon.gamechatnest.socket.ChatMessageClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.BulkOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.Deque;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author : Qik 2024/5/15 11:36
 */
@Service
public class ChannelChatMessageServiceImpl implements ChannelChatMessageService {

    @Autowired
    @Lazy
    private TextChannelService textChannelService;

    @Autowired
    @Lazy
    private ServerMembersService serverMembersService;

    @Autowired
    private MongoTemplate mongoTemplate;


    @Override
    public Result syncMessage(Long userId) {
        List<ChatMessage> chatMessages = mongoTemplate.findAllAndRemove(
                new Query(Criteria.where("userId").is(userId)),
                ChatMessage.class, Constant.CHANNEL_SYNCHRONIZE_MESSAGE
        );
        return ResultBuild.result().state(RespStatus.MESSAGE_SYNCHRONIZATION_SUCCESSFUL).data(chatMessages).build();
    }

    @Override
    public void handleMessage(ConcurrentHashMap<Long, ChatMessageClient> webSocketMap, ChatMessage chatMessage) {
        // 获取登录用户id
//        Long loginUserId = SecurityUtil.getUserId();

        // 发送用户id
        Long userId = chatMessage.getFromUser();

        // 当前用户的响应队列
        Deque<Object> responseQueue = webSocketMap.get(userId).getResponseQueue();

        // 根据发送信息目标id获取频道
        TextChannel textChannel = textChannelService.findByTcId(chatMessage.getTargetId());
        // 频道不存在
        if (Objects.isNull(textChannel)) {
            // 获取用户会话，返回结果信息
            responseQueue.addFirst(ResultBuild.result().failed().message("非法频道").build());
            return;
        }

        // 获取频道id
        Long serverId = textChannel.getServerId();
        // 根据频道id获取频道所在服务器成员id列表
        List<Long> userIdList = serverMembersService.getUserIdByServerId(serverId);
        // 开启批量
        BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, ChannelSyncMessageDto.class);
        // 流执行在线发送，不在线保存到bulkOperations，之后保存到同步文档
        userIdList.stream().filter(uid -> !uid.equals(userId)).forEach(uid -> {

            ChatMessageClient chatMessageClient = webSocketMap.get(uid);
            // 会话不存在,添加到同步消息库
            if (Objects.isNull(chatMessageClient)) {
                bulkOperations.insert(new ChannelSyncMessageDto(null, uid, chatMessage.getTargetId(), chatMessage.getId(), new Date()));
                return;
            }
            // 会话存在，发送信息给对方
            chatMessageClient.getResponseQueue().addFirst(chatMessage);
        });
        // 执行批量操作
        bulkOperations.execute();
        // 保存到历史消息库
        mongoTemplate.save(chatMessage, Constant.CHANNEL_HISTORICAL_MESSAGE);

        // 获取用户会话，返回结果信息
        responseQueue.addFirst(ResultBuild.result().successful().data(chatMessage).build());
    }
}
